package it.polimi.swKnights.SWIMv2.ejb.captchaGenerator;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.ejb.Stateless;

@Stateless
public class CaptchaGenerator implements CaptchaGeneratorRemote
{
	private Random random = new Random();

	private static final int ten = 10;

	private static final int twenty = 20;

	private static final int hundred = 100;

	private static final int thousand = 1000;

	private static final int million = 1000000;

	private static final int billion = 1000000000;

	private static final Map<Integer, String> littleNumber = getLittleNumberMap();

	private static final Map<Integer, String> tens = getTens();

	private static final Map<Integer, String> highNumbers = getHigNumbers();

	@Override
	public int getCaptcha()
	{
		int key = this.random.nextInt(2*thousand);
		return key;
	}

	@Override
	public boolean validateCaptcha(int key, String value)
	{
		//delete all white spaces, comma and minus from the response
		String shortValue = value.replace(" ","").replace(",", "").replace("-", "");
		//delete all white spaces from the solution
		String solution = this.toLetters(key).replace(" ","");

		return shortValue.equalsIgnoreCase(solution);
	}

	private static Map<Integer, String> getHigNumbers()
	{
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(hundred, "hundred");
		map.put(thousand, "thousand");
		map.put(million, "million");
		map.put(billion, "billion");
		return map;
	}

	private static Map<Integer, String> getTens()
	{
		Map<Integer, String> map = new HashMap<Integer, String>();
		String[] numbers = { "twenty", "thirty", "forty", "fifty", "sixty",
				"seventy", "eighty", "ninety" };
		for (int i = 0; i < numbers.length; i++)
		{
			map.put(i + 2, numbers[i]);
		}
		return map;
	}

	private static Map<Integer, String> getLittleNumberMap()
	{
		Map<Integer, String> map = new HashMap<Integer, String>();
		String[] numbers = { "", "one", "two", "three", "four", "five", "six",
				"seven", "eight", "nine", "ten", "eleven", "twelve",
				"thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
				"eighteen", "nineteen" };
		for (int i = 0; i < numbers.length; i++)
		{
			map.put(i, numbers[i]);
		}
		return map;
	}

	private String toLetters(int key)
	{
		int currentValue = key;

		if (currentValue == 0)
		{
			return "zero";
		}
		else if (currentValue < twenty)
		{
			return littleNumber.get(currentValue);
		}
		else if (currentValue < hundred)
		{
			return tens.get(currentValue / ten)
					+ littleNumber.get(currentValue % ten);
		}
		else if (currentValue < thousand)
		{
			return this.toLetters(currentValue / hundred) + " "
					+ highNumbers.get(hundred) + " "
					+ this.toLetters(currentValue % hundred);
		}
		else if (currentValue < million)
		{
			return this.toLetters(currentValue / thousand) + " "
					+ highNumbers.get(thousand) + " "
					+ this.toLetters(currentValue % thousand);
		}
		else if (currentValue < billion)
		{
			return this.toLetters(currentValue / million) + " "
					+ highNumbers.get(million) + " "
					+ this.toLetters(currentValue % million);
		}
		else
		{
			return this.toLetters(currentValue / billion) + " "
					+ highNumbers.get(billion) + " "
					+ this.toLetters(currentValue % billion);
		}
	}
}
